package com.bit.cfdi.web.vm.productservices;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.zkoss.bind.BindContext;
import org.zkoss.bind.annotation.BindingParam;
import org.zkoss.bind.annotation.Command;
import org.zkoss.bind.annotation.ContextParam;
import org.zkoss.bind.annotation.ContextType;
import org.zkoss.bind.annotation.Init;
import org.zkoss.bind.annotation.NotifyChange;
import org.zkoss.zk.ui.event.DropEvent;
import org.zkoss.zk.ui.select.annotation.VariableResolver;
import org.zkoss.zul.Listitem;
import com.bit.cfdi.web.biobjects.BIListItem;

@VariableResolver(org.zkoss.zkplus.spring.DelegatingVariableResolver.class)
public class ModalWindowImportProductServiceViewModel {

	private static final String LEFT_LIST = "left_list";
	private static final String RIGHT_LIST = "right_list";
		
	private String color;	
	private List<BIListItem> listLeft;
	private List<BIListItem> listRight;
	private Map<Integer, Integer> mapping;
	private Boolean activeChk;
	private Boolean statusChk;
	
	private Logger log = LogManager.getLogger(this.getClass().getName());
	private Integer indexTabbox;
	private String textTitle;

	@Init
	public void init()
	{
		listLeft = new ArrayList<BIListItem>();
		listRight = new ArrayList<BIListItem>();
		mapping = new HashMap<Integer, Integer>();
		fillLeftList();
		fillRightList();
		validateLongList();
		
		indexTabbox = 0;	
		textTitle = "Selecciona la ruta donde se exportarán los datos";
	}
		
	public Integer getIndexTabbox() {
		return indexTabbox;
	}

	public void setIndexTabbox(Integer indexTabbox) {
		this.indexTabbox = indexTabbox;
	}
		
	public String getTextTitle() {
		return textTitle;
	}

	public String getColor() {
		return color;
	}

	public List<BIListItem> getListLeft() {
		return listLeft;
	}

	public List<BIListItem> getListRight() {
		return listRight;
	}
	
	/*------------------------*/
	
	@Command
	@NotifyChange({"indexTabbox","textTitle"})
	public void goPagePrevisualizacion()
	{
		indexTabbox = 2;
		textTitle = "Previsualización de la importación.";
	}
	
	@Command
	@NotifyChange({"indexTabbox","textTitle"})
	public void goPagePath()
	{
		indexTabbox = 0;
		textTitle = "Selecciona el archivo para importar los datos";
	}	
		
	@Command
	@NotifyChange({"indexTabbox","textTitle"})
	public void goPageMapping()
	{
		indexTabbox = 1;
		textTitle = "Mapeo de los campos";
	}
	
	/*-----*/
	public Boolean getActiveChk() {
		return activeChk;
	}

	public Boolean getStatusChk() {
		return statusChk;
	}

	public void setStatusChk(Boolean statusChk) {
		this.statusChk = statusChk;
	}

	private void fillLeftList()
	{
		for(int i = 0 ; i < 8; i++)
		{			
			BIListItem item = new BIListItem();
			item.setLabel("elemento " + i);
			String color = getRandomColor();
			item.setColor(color);
			listLeft.add(item);
		}		
	}
	
	private void fillRightList()
	{
		for(int i = 0 ; i < 8; i++)
		{
			BIListItem item = new BIListItem();
			item.setLabel("Producto/Servicio " + i);
			listRight.add(item);
		}
	}
		
	private void validateLongList()
	{
		if(listLeft.size() == listRight.size())
		{
			activeChk = true;
		}
		else
		{
			activeChk = false;
		}
	}
	
	public String getRandomColor()
	{
		StringBuilder strb = new StringBuilder();
		strb.append((char)35);
		for(int i = 0; i < 6; i++ )
		{
			int numero = (int) (4 + (Math.random() * 12));
			if(numero < 10)
			{				
				numero = numero + 48;
				strb.append((char)numero);
			}
			else
			{
				numero = numero  + 55;
				strb.append((char)numero);
			}
		}
		return strb.toString();
	}
	
	@Command
	@NotifyChange({"listRight"})
	public void onCheckEvent(@BindingParam("isChecked")Boolean isCheked)
	{
		if(isCheked)
		{
			for(int i = 0; i < listLeft.size(); i++)
			{
				addToMap(i, i);
			}
		}		
		else
		{
			clearRelations();
		}
	}
	
	/*----------Trabajando sobre el drag an drop---------*/	
	
	@Command
	@NotifyChange({"listRight"})
	public void clearRelations() {
		mapping = new HashMap<Integer, Integer>();
		cleanRightListStyles();
	}
	
	@Command @NotifyChange({"listLeft","listRight"})
	public void onDropListitemEvent(@ContextParam(ContextType.BIND_CONTEXT) BindContext ctx)
	{			
		DropEvent evt = (DropEvent) ctx.getTriggerEvent();
		Listitem dragged = null;
		Listitem target = null;
		Integer leftPos, rightPos;
		if(evt.getDragged() instanceof Listitem) {
			dragged = (Listitem) evt.getDragged();
		}
		if(evt.getTarget() instanceof Listitem) {
			target = (Listitem) evt.getTarget();
		}
		if(dragged == null || target == null) {
			log.error("Dragged or Target null");
			return;
		}
		if(dragged.getParent().getId().equals(target.getParent().getId())) {
			log.error("Dragged and Dropped on the same list");
			return;
		}		
		if(dragged.getParent().getId().equals(LEFT_LIST)) {
			leftPos = dragged.getIndex();
			rightPos = target.getIndex();
		}
		else {
			leftPos = target.getIndex();
			rightPos = dragged.getIndex();
		}
		addToMap(leftPos, rightPos);
	}
	
	private void addToMap(Integer leftPos, Integer rightPos) {
		log.info("leftPos: "+leftPos.intValue()+" rightPos: "+rightPos.intValue());
		removePreviousValue(rightPos);
		mapping.put(leftPos, rightPos);
		cleanRightListStyles();
		transferStyles();
	}
	
	private void removePreviousValue(final Integer rightPos) {
		List<Integer> toRemoveItems = new ArrayList<Integer>();
		for(Integer currentKey : mapping.keySet()) {
			if(mapping.get(currentKey).equals(rightPos)) {
				toRemoveItems.add(currentKey);
			}
		}
		if(!toRemoveItems.isEmpty()) {
			for(Integer toRemove : toRemoveItems) {
				mapping.remove(toRemove);
			}
		}
	}
	
	private void cleanRightListStyles() {
		for(BIListItem currentItem : listRight) {
			currentItem.setColor(null);
		}
	}
	
	private void transferStyles() {
		log.info("------------------------------------------------");
		for(Integer key : mapping.keySet()) {
			BIListItem leftObj = listLeft.get(key.intValue());
			BIListItem rightObj = listRight.get(mapping.get(key).intValue());
			rightObj.setColor(leftObj.getColor());			
			log.info(key.intValue() + " " + mapping.get(key).intValue());
		}		
	}
	
}